#include<iostream>
using namespace std;

template<class T>
struct Node{
    T value;
    Node*next;
    Node(T&t){
        value=t;
        next=nullptr;     
    }
};

//链表方向从队头指向队尾
template<class T>
class linkedQueue{
private:
    Node<T>*head;
    Node<T>*rear;
    int size;
public:
    linkedQueue(){
        size=0;
        head=rear=nullptr;
    };
    ~linkedQueue(){
        Node<T>*ptr=this->head;
        while(ptr!=nullptr){
            Node<T>*cur=ptr;
            ptr=ptr->next;
            delete cur;
        }
    }

    bool isEmpty()const{
        return size==0;
    }
    int getSize()const{
        return this->size;
    }
    void push(T&e);
    void pop();
    T&getHead()const;
    T&getRear()const;
};

template<class T>
void linkedQueue<T>::push(T&e){
    if(size==0){
        head=new Node<T>(e);
        rear=head;
    }
    else{
        rear->next=new Node<T>(e);
        rear=rear->next;
    }
    size++;
}

template<class T>
void linkedQueue<T>::pop(){
    if(size==0){
        cout<<"The queue is empty;"<<endl;
        return;
    }
    Node<T>*cur=head;
    head=head->next;
    if(size==1)
        rear=head;
    delete cur;
    size--;
}

template<class T>
T& linkedQueue<T>::getHead()const{
    if(size==0){
        throw 0;//自定义异常也可
    }
    return head->value;
}

template<class T>
T& linkedQueue<T>::getRear()const{
    if(size==0){
        throw 0;//自定义异常也可
    }
    return rear->value;
}

int main(){
    linkedQueue<int>l_queue;
    int*ptr=new int;

    *ptr=1;
    l_queue.push(*ptr);
    cout<<"Front is: "<<l_queue.getHead()<<" Rear is: "<<l_queue.getRear()<<endl;

    *ptr=2;
    l_queue.push(*ptr);
    cout<<"Front is: "<<l_queue.getHead()<<" Rear is: "<<l_queue.getRear()<<endl;

    *ptr=3;
    l_queue.push(*ptr);
    cout<<"Front is: "<<l_queue.getHead()<<" Rear is: "<<l_queue.getRear()<<endl;

    l_queue.pop();
    cout<<"Front is: "<<l_queue.getHead()<<" Rear is: "<<l_queue.getRear()<<endl;

    l_queue.pop();
    cout<<"Front is: "<<l_queue.getHead()<<" Rear is: "<<l_queue.getRear()<<endl;

    l_queue.pop();
    cout<<"Front is: "<<l_queue.getHead()<<" Rear is: "<<l_queue.getRear()<<endl;
    return 0;
}